package com.yuanjun.product.utils;

import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;
import com.yuanjun.product.config.CCommonSettings;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.UUID;

public class OssUtil {
    private static final Logger LOGGER = LoggerFactory.getLogger(OssUtil.class);

    private static void ensureBucket(OSSClient client, String bucketName)
            throws OSSException, ClientException {
        if (client.doesBucketExist(bucketName)) {
            return;
        }

        client.createBucket(bucketName);
    }

    private static void setBucketPublicReadable(OSSClient client, String bucketName)
            throws OSSException, ClientException {
        client.createBucket(bucketName);

        client.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
    }

    private static OSSClient getClient() {
        String access_Id = CCommonSettings.getProperty("oss.accessId");
        String access_Key = CCommonSettings.getProperty("oss.accessKey");
        String endPoint = CCommonSettings.getProperty("oss.endPointUrl");

        ClientConfiguration config = new ClientConfiguration();
        OSSClient client = new OSSClient(endPoint, access_Id, access_Key, config);

        return client;
    }

    private static OSSClient getAudioClient() {
        String access_Id = CCommonSettings.getProperty("oss.accessId");
        String access_Key = CCommonSettings.getProperty("oss.accessKey");
        String endPoint = CCommonSettings.getProperty("oss.internal.endPointUrl");
        ClientConfiguration config = new ClientConfiguration();
        OSSClient client = new OSSClient(endPoint, access_Id, access_Key, config);
        return client;
    }

    public static boolean uploadFile(String key, File file, byte type) {
        boolean result = true;

        OSSClient client = getClient();
        String bucketName = "";
        //type 1 非加密的 2 加密
        if (type == 1) {
            bucketName = CCommonSettings.getProperty("oss.bucket.public");
        } else if (type == 2) {
            bucketName = CCommonSettings.getProperty("oss.bucket.private");
        }

        try {
            ensureBucket(client, bucketName);

            ObjectMetadata objectMeta = new ObjectMetadata();
            objectMeta.setContentLength(file.length());
            objectMeta.setHeader("x-oss-server-side-encryption", "AES256");

            String fileName = file.getName();
            String extFile = fileName.substring(fileName.lastIndexOf("."));

            objectMeta.setContentType(getContentType(extFile));

            InputStream input = new FileInputStream(file);

            client.putObject(bucketName, key, input, objectMeta);
        } catch (Exception e) {
            result = false;
            LOGGER.error(String.valueOf(e));
        }

        return result;
    }

    public static String uploadFile(String fileName, String group, InputStream inputStream, byte type) {
        String result = null;
        OSSClient client = null;
        if("audio".equals(group)){
            client = getAudioClient();
        }else{
            client = getClient();
        }
        String bucketName = "";
        //type 1 非加密的 2 加密
        if (type == 1) {
            bucketName = CCommonSettings.getProperty("oss.bucket.public");
        } else if (type == 2) {
            bucketName = CCommonSettings.getProperty("oss.bucket.private");
        }
        try {
            String fileType = FilenameUtils.getExtension(fileName).toLowerCase(Locale.ENGLISH);

            String newFileName = UUID.randomUUID().toString() + "_" + DateUtil.format(new Date(), "HHmmss") + "." + fileType;
            String key = group + "/" + DateUtil.format(new Date(), "yyyy/MM/dd") + "/" + newFileName;

            ensureBucket(client, bucketName);

            ObjectMetadata objectMeta = new ObjectMetadata();

            BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);

            LOGGER.info("文件大小：{}", bufferedInputStream.available());
            objectMeta.setContentLength(bufferedInputStream.available());
            objectMeta.setHeader("x-oss-server-side-encryption", "AES256");
            objectMeta.setCacheControl("no-cache");
            fileName = key;
            String extFile = fileName.substring(fileName.lastIndexOf("."));

            objectMeta.setContentType(getContentType(extFile));
            result = key;

            client.putObject(bucketName, key, inputStream, objectMeta);
        } catch (Exception e) {
            result = null;
            LOGGER.error(String.valueOf(e));
        }

        return result;
    }

    public static boolean deleteObject(String key, byte type) {
        boolean result = true;
        OSSClient client = getClient();
        String bucketName = "";
        //type 1 非加密的 2 加密
        if (type == 1) {
            bucketName = CCommonSettings.getProperty("oss.bucket.public");
        } else if (type == 2) {
            bucketName = CCommonSettings.getProperty("oss.bucket.private");
        }
        try {
            client.deleteObject(bucketName, key);
        } catch (Exception e) {
            result = false;
        }
        return result;
    }

    public static InputStream getFileInputStream(String key, byte type)
            throws OSSException, ClientException {
        OSSClient client = getClient();
        String bucketName = "";
        //type 1 非加密的 2 加密
        if (type == 1) {
            bucketName = CCommonSettings.getProperty("oss.bucket.public");
        } else if (type == 2) {
            bucketName = CCommonSettings.getProperty("oss.bucket.private");
        }
        OSSObject fileObject = client.getObject(bucketName, key);
        return fileObject.getObjectContent();
    }

    public static String getContentType(String fileType) {
        return MimeTypeUtil.getMimeType(fileType);
    }

    public static void getObjects() {
        OSSClient ossClient = getClient();
        final int maxKeys = 200;
        String nextMarker = null;
        ObjectListing objectListing;
        CopyObjectRequest copyObjectRequest;
        String srcBucketName = "jk-project-private";
        ObjectMetadata meta;
        do {
            objectListing = ossClient.listObjects(new ListObjectsRequest("jk-project-private").withMarker(nextMarker).withMaxKeys(maxKeys));
            List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
            for (OSSObjectSummary s : sums) {
//                copyObjectRequest(s.getBucketName(), s.getKey(), s.getSize());
            }
            nextMarker = objectListing.getNextMarker();
        } while (objectListing.isTruncated());
    }

    public static void copyObjectRequest(String bucketName, String key, Long size) {
        OSSClient ossClient = getClient();
//        String bucketName = "jk-project-private";
//        String key = "image/2018/04/25/489db72d-7904-4210-ad1a-c187f6edb5f6_141741.png";
        CopyObjectRequest copyObjectRequest = new CopyObjectRequest(bucketName, key, bucketName, key);
        ObjectMetadata meta = new ObjectMetadata();
        meta.setHeader("x-oss-server-side-encryption", "AES256");
        meta.setCacheControl("no-cache");
        String fileName = key;
        String extFile = fileName.substring(fileName.lastIndexOf("."));
        meta.setContentType(getContentType(extFile));
        meta.setContentLength(size);
        copyObjectRequest.setNewObjectMetadata(meta);
        CopyObjectResult result = ossClient.copyObject(copyObjectRequest);
        LOGGER.info("ETag:{} LastModified:{}", result.getETag(), result.getLastModified());
    }

    public static String getBucketUrl(String photoUrl) {
        if (StringUtils.isEmpty(photoUrl)) {
            return "";
        }
        OSSClient client = getClient();
        Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000);
        URL url = client.generatePresignedUrl(CCommonSettings.getProperty("oss.bucket.private"), photoUrl.substring(photoUrl.indexOf("image"), photoUrl.length()), expiration);
        return url + "";
    }

    public static void main(String[] args) throws Exception {
        getObjects();
//        copyObjectRequest();
    }
}
